﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Collections;
using System.Text;
using System.Data;
using System.Reflection;
using System.Text.RegularExpressions;


/// <summary>
/// JsonHelper 的摘要说明  .net 4.0 需引用 System.Runtime.Serialization  System.Web.Extensions
/// </summary>
public static class JsonHelper
{
    /// <summary>
    /// 转换DataTable为JSON格式数据  转换结果与List<T>保持一致
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string ToJson(DataTable dt)
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        ArrayList al = new ArrayList();
        foreach (DataRow dr in dt.Rows)
        {
            Dictionary<string, object> info = new Dictionary<string, object>();
            foreach (DataColumn dc in dt.Columns)
            {
                info.Add(dc.ColumnName, dr[dc]);
            }
            al.Add(info);
        }
        return jss.Serialize(al); ;
    }
    /// <summary>
    /// 转换对象为JSON格式数据   js读取DateTime类型方式： new Date(parseInt('/Date(1433820938220)/'.slice(6, 19)));
    /// </summary>
    /// <param name="obj">对象</param>
    /// <returns>JSON格式数据</returns>
    public static string ToJson(object obj)
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        return jss.Serialize(obj);
    }
    /// <summary>
    /// JSON格式字符转换为T类型的对象
    /// </summary>
    /// <typeparam name="T">类</typeparam>
    /// <param name="json">JSON格式数据</param>
    /// <returns>对象</returns>
    public static T GetT<T>(string json)
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        T o = jss.Deserialize<T>(json);
        return LocalTime<T>(o);
    }

    /// <summary>
    /// 修复 Json 转类型后没有将UTC时间 转换成 本地时间 的BUG
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="o"></param>
    /// <returns></returns>
    private static T LocalTime<T>(T o)
    {
        Type t = o.GetType();
        Type dt = typeof(DateTime);
        if (t.IsGenericType)
        {
            foreach (object x in (o as IEnumerable))
            {
                LocalTime<object>(x);
            }
            return o;
        }
        else
        {
            PropertyInfo[] pil = t.GetProperties();
            foreach (PropertyInfo pi in pil)
            {
                if (pi.PropertyType == dt)
                {
                    pi.SetValue(o, ((DateTime)pi.GetValue(o, null)).ToLocalTime(), null);
                }
            }
            return o;
        }
    }

    /// <summary>
    /// 转换DataTable为JSON格式数据  转换结果 键值都以String类型存储
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static string GetJson(DataTable dt)
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        ArrayList al = new ArrayList();
        foreach (DataRow dr in dt.Rows)
        {
            Dictionary<string, string> info = new Dictionary<string, string>();
            foreach (DataColumn dc in dt.Columns)
            {
                info.Add(dc.ColumnName, dr[dc].ToString());
            }
            al.Add(info);
        }
        return jss.Serialize(al);
    }

    /// <summary>
    /// 转换对象为JSON格式数据   转换结果 键值都以String类型存储
    /// </summary>
    /// <param name="obj">对象</param>
    /// <returns>JSON格式数据</returns>
    public static string GetJson(object o)
    {
        if (o.GetType().IsGenericType)
        {
            return ArrayToJson(o);
        }
        else
        {
            return ModelToJson(o);
        }
    }

    /// <summary>
    /// 转换List对象为JSON格式数据
    /// </summary>
    /// <param name="o">对象</param>
    /// <returns>JSON格式数据</returns>
    private static string ArrayToJson(object o)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("[");
        bool IsRun = false;
        foreach (object x in (o as IEnumerable))
        {
            sb.Append(string.Format(",{0}", ModelToJson(x))); IsRun = true;
        }
        if (IsRun) sb.Remove(1, 1);
        sb.Append("]");
        return sb.ToString();
    }

    /// <summary>
    /// 转换普通对象为JSON格式数据
    /// </summary>
    /// <param name="o">对象</param>
    /// <returns>JSON格式数据</returns>
    private static string ModelToJson(object o)
    {
        Type t = o.GetType();
        PropertyInfo[] pil = t.GetProperties();
        StringBuilder sb = new StringBuilder();
        sb.Append("{");
        foreach (PropertyInfo pi in pil)
        {
            sb.Append(string.Format(",\"{0}\":\"{1}\"", pi.Name, pi.GetValue(o, null).ToString().Replace("\"", "\\\"")));
        }
        if (pil.Length > 0) sb.Remove(1, 1);
        sb.Append("}");
        return sb.ToString();
    }

}

public class Json
{
    private object o;

    private Dictionary<string, object> d;
    private ArrayList l;

    private static Regex reg_json = new Regex("^{.*}$");
    private static Regex reg_list = new Regex(@"^\[.*\]$");
    private static JavaScriptSerializer jss = new JavaScriptSerializer();

    public Json() { }
    public Json(string json)
    {
        if (reg_json.IsMatch(json))
            o = jss.Deserialize<Dictionary<string, object>>(json);
        else if (reg_list.IsMatch(json))
            o = jss.Deserialize<ArrayList>(json);
        else
            o = json;
    }
    public Json(object o)
    {
        this.o = o;
    }
    public Json this[string key]
    {
        get
        {
            d = (Dictionary<string, object>)o;
            if (d != null && d.ContainsKey(key))
                return new Json(d[key]);
            else
                return null;
        }
        set
        {
            if (o == null) o = jss.Deserialize<object>("{}");
            d = (Dictionary<string, object>)o;
            if (value == null)
                d.Remove(key);
            else
                d[key] = value.o;
        }
    }

    public Json this[int index]
    {
        get
        {
            if (o != null)
            {
                if (o.GetType() == typeof(ArrayList))
                {
                    l = (ArrayList)o;
                    if (l.Count > index)
                        return new Json(l[index]);
                    else
                        return null;
                }
                else
                {
                    d = (Dictionary<string, object>)o;
                    if (d.Count > index)
                        return new Json(d.ElementAt(index).Value);
                    else
                        return null;
                }
            }
            else
                return null;
        }
        set
        {
            if (o.GetType() == typeof(ArrayList))
            {
                l = (ArrayList)o;
                if (l.Count > index)
                    l[index] = value;
            }
            else
            {
                d = (Dictionary<string, object>)o;
                if (d.Count > index)
                {
                    string key = d.ElementAt(index).Key;
                    if (value == null)
                        d.Remove(key);
                    else
                        d[key] = value;
                }
            }
        }
    }

    public void Add(string json)
    {
        if (o == null) o = jss.Deserialize<ArrayList>("[]");
        l = (ArrayList)o;
        l.Add(jss.Deserialize<object>(json));
    }

    public int Count
    {
        get
        {
            if (o != null)
            {
                if (o.GetType() == typeof(ArrayList))
                {
                    return ((ArrayList)o).Count;
                }
                else
                {
                    return ((Dictionary<string, object>)o).Count;
                }
            }
            else
                return 0;
        }
    }


    public override string ToString()
    {
        if (o != null)
        {
            Type t = o.GetType();
            if (t == typeof(ArrayList))
                return jss.Serialize(o);
            else if (t == typeof(Dictionary<string, object>))
                return jss.Serialize(o);
            else
                return o.ToString();
        }
        else
            return string.Empty;
    }
    public static implicit operator string(Json j)
    {
        if (j == null)
            return string.Empty;
        else
            return j.ToString();
    }
    public static implicit operator Json(string s)
    {
        return new Json(s);
    }
    public static implicit operator Json(DateTime dt)
    {
        return new Json(dt);
    }
    public static implicit operator Json(bool b)
    {
        return new Json(b);
    }
    public static implicit operator Json(int i)
    {
        return new Json(i);
    }

}


